using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Properties;

namespace ICSharpCode.TextEditor
{
	public class GutterMargin : AbstractMargin, IDisposable
	{
		private StringFormat numberStringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();

		public static Cursor RightLeftCursor;

		public override Cursor Cursor => GutterMargin.RightLeftCursor;

		public override Size Size => new Size(base.textArea.TextView.WideSpaceWidth * Math.Max(3, (int)Math.Log10(base.textArea.Document.TotalNumberOfLines) + 1), -1);

		public override bool IsVisible => base.textArea.TextEditorProperties.ShowLineNumbers;

		static GutterMargin()
		{
			using MemoryStream stream = new MemoryStream(Resources.RightArrow);
			GutterMargin.RightLeftCursor = new Cursor(stream);
		}

		public void Dispose()
		{
			this.numberStringFormat.Dispose();
		}

		public GutterMargin(TextArea textArea)
			: base(textArea)
		{
			this.numberStringFormat.LineAlignment = StringAlignment.Far;
			this.numberStringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap | StringFormatFlags.NoClip;
		}

		public override void Paint(Graphics g, Rectangle rect)
		{
			if (rect.Width <= 0 || rect.Height <= 0)
			{
				return;
			}
			HighlightColor colorFor = base.textArea.Document.HighlightingStrategy.GetColorFor("LineNumbers");
			int fontHeight = base.textArea.TextView.FontHeight;
			Brush brush = (base.textArea.Enabled ? BrushRegistry.GetBrush(colorFor.BackgroundColor) : SystemBrushes.InactiveBorder);
			Brush brush2 = BrushRegistry.GetBrush(colorFor.Color);
			for (int i = 0; i < (base.DrawingPosition.Height + base.textArea.TextView.VisibleLineDrawingRemainder) / fontHeight + 1; i++)
			{
				int y = base.drawingPosition.Y + fontHeight * i - base.textArea.TextView.VisibleLineDrawingRemainder;
				Rectangle rectangle = new Rectangle(base.drawingPosition.X, y, base.drawingPosition.Width, fontHeight);
				if (rect.IntersectsWith(rectangle))
				{
					g.FillRectangle(brush, rectangle);
					int firstLogicalLine = base.textArea.Document.GetFirstLogicalLine(base.textArea.Document.GetVisibleLine(base.textArea.TextView.FirstVisibleLine) + i);
					if (firstLogicalLine < base.textArea.Document.TotalNumberOfLines)
					{
						g.DrawString((firstLogicalLine + 1).ToString(), colorFor.GetFont(base.TextEditorProperties.FontContainer), brush2, rectangle, this.numberStringFormat);
					}
				}
			}
		}

		public override void HandleMouseDown(Point mousepos, MouseButtons mouseButtons)
		{
			base.textArea.SelectionManager.selectFrom.where = 1;
			int logicalLine = base.textArea.TextView.GetLogicalLine(mousepos.Y);
			if (logicalLine < 0 || logicalLine >= base.textArea.Document.TotalNumberOfLines)
			{
				return;
			}
			if ((Control.ModifierKeys & Keys.Shift) != 0)
			{
				if (!base.textArea.SelectionManager.HasSomethingSelected && logicalLine != base.textArea.Caret.Position.Y)
				{
					if (logicalLine >= base.textArea.Caret.Position.Y)
					{
						TextLocation position = base.textArea.Caret.Position;
						if (logicalLine < base.textArea.Document.TotalNumberOfLines - 1)
						{
							base.textArea.SelectionManager.SetSelection(new DefaultSelection(base.textArea.Document, position, new TextLocation(0, logicalLine + 1)));
							base.textArea.Caret.Position = new TextLocation(0, logicalLine + 1);
						}
						else
						{
							base.textArea.SelectionManager.SetSelection(new DefaultSelection(base.textArea.Document, position, new TextLocation(base.textArea.Document.GetLineSegment(logicalLine).Length + 1, logicalLine)));
							base.textArea.Caret.Position = new TextLocation(base.textArea.Document.GetLineSegment(logicalLine).Length + 1, logicalLine);
						}
					}
					else
					{
						TextLocation position = base.textArea.Caret.Position;
						base.textArea.SelectionManager.SetSelection(new DefaultSelection(base.textArea.Document, position, new TextLocation(position.X, position.Y)));
						base.textArea.SelectionManager.ExtendSelection(new TextLocation(position.X, position.Y), new TextLocation(0, logicalLine));
						base.textArea.Caret.Position = new TextLocation(0, logicalLine);
					}
				}
				else
				{
					MouseEventArgs e = new MouseEventArgs(mouseButtons, 1, mousepos.X, mousepos.Y, 0);
					base.textArea.RaiseMouseMove(e);
				}
			}
			else
			{
				base.textArea.mousepos = mousepos;
				TextLocation position = new TextLocation(0, logicalLine);
				base.textArea.SelectionManager.ClearSelection();
				if (logicalLine < base.textArea.Document.TotalNumberOfLines - 1)
				{
					base.textArea.SelectionManager.SetSelection(new DefaultSelection(base.textArea.Document, position, new TextLocation(position.X, position.Y + 1)));
					base.textArea.Caret.Position = new TextLocation(position.X, position.Y + 1);
				}
				else
				{
					base.textArea.SelectionManager.SetSelection(new DefaultSelection(base.textArea.Document, new TextLocation(0, logicalLine), new TextLocation(base.textArea.Document.GetLineSegment(logicalLine).Length + 1, position.Y)));
					base.textArea.Caret.Position = new TextLocation(base.textArea.Document.GetLineSegment(logicalLine).Length + 1, position.Y);
				}
			}
		}
	}
}
